//
//  Race.m
//  Racing
//
//  Created by vy phan on 4/17/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Race.h"


@implementation Race
// Constructors
-(id) initWithTrack:(Track*)track_ Vehicles:(NSMutableArray*)vehicles_
{
	self = [super init];
	if (self != nil) {
		track = [[Track alloc]init];
		vehicles = [[NSMutableArray alloc]init];
		
		self->track = track_;
		self->vehicles = vehicles_;
		int num_vehicles = [vehicles count];
		
		currentSections = [[NSMutableArray alloc]initWithCapacity:num_vehicles];
		nextSections = [[NSMutableArray alloc]initWithCapacity:num_vehicles];
		ranks = [[NSMutableArray alloc]initWithCapacity:num_vehicles];
		trackCounts = [[NSMutableArray alloc]initWithCapacity:num_vehicles];
		
		for (int i = 0; i < num_vehicles; i++) {
			[currentSections addObject:[NSNumber numberWithInt:0]];
			[nextSections addObject:[NSNumber numberWithInt:0]];
			[ranks addObject:[NSNumber numberWithInt:0]];
			[trackCounts addObject:[NSNumber numberWithInt:0]];
		}
		
		lightsStarted = -1;
		lightsDone = NO;
		currentLight = 0;
	}
	return self;
	
}

-(id) initWithLocalVehicle:(Vehicle*)local Track:(Track*)track_ Vehicles:(NSMutableArray*)vehicles_
{
	self = [self initWithTrack:track_ Vehicles:vehicles_];
	self->localVehicle = [[Vehicle alloc]init];
	self->localVehicle = local;
	return self;
}

-(void) reset
{
	int vehiclesCount = [vehicles count];
	for ( int i = 0; i < vehiclesCount; i++) {
		[currentSections replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
		[nextSections replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
		[ranks replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:1]];
		[trackCounts replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
	}
	if (track->sections != nil) {
		[track toStartingPositions:vehicles];
	}
	lightsStarted = -1;
	lightsDone = NO;
	currentLight = 0;
}

-(int) getRank:(Vehicle*)vehicle_ 
{
	return (int)[ranks objectAtIndex:[vehicle_ getId]];
}

-(NSMutableArray*) getRanks
{
	return ranks;
}

-(int) getTrackCount:(Vehicle*)vehicle_ 
{
	return (int)[trackCounts objectAtIndex:[vehicle_ getId]];
}

-(int) getNumLaps
{
	return numLaps;
}

-(NSMutableArray*) getTrackCounts
{
	return trackCounts;
}

-(Track*) getTrack
{
	return track;
}

-(NSMutableArray*) getVehicles
{
	return vehicles;
}

-(int) getCurrentLight
{
	return currentLight;
}
-(void) integrate:(float)dt
{
	BOOL collision = NO;
	BOOL racing = NO;
	
//	// cap nhat den xanh do luc bat dau
//	if ( !lightsDone ) {
//		if ( lightsStarted == -1 )
//			lightsStarted += dt;
//		
//		if ( lightsStarted > 4 ) {
//			currentLight = 4;
//			lightsDone = YES;
//		}
//		else if ( lightsStarted > 3 ) {
//			currentLight = 3;
//		}
//		else if ( lightsStarted > 2 ) {
//			currentLight = 2;
//		}
//		else if ( lightsStarted > 1 ) {
//			currentLight = 1;
//		}
//		
//	}
//	else {	
		racing = YES;
		int vehiclesCount = [vehicles count];
		for ( int i = 0; i < vehiclesCount; i++ ) {
			Vehicle *vehicle = [vehicles objectAtIndex:i];
			[vehicle integrate:dt];
			
//			nextSections[ i ] = track.checkCollisions(
//													  vehicle,
//													  vehicle.nextState(),
//													  currentSections[ i ] );
//			
//			[nextSections replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:<#(int)value#>]];
			if ( [(State*)[vehicle nextState] isColliding] ) {
				collision = YES;
			}
		}
//	}
	
	
	//if ( [self chec] ) collision = true;
	// end
	if (YES)
	{
	//int vehiclesCount = [vehicles count];
	int lastSection = [track->sections count] - 1;
	for ( int i = 0; i < vehiclesCount; i++ ) {
		Vehicle *vehicle = (Vehicle*)[vehicles objectAtIndex:i];
		//[[vehicle nextState] computeCollisions];
		[vehicle update];
		int currentSection = [[currentSections objectAtIndex:i] intValue];
		int nextSection = [[nextSections objectAtIndex:i] intValue];
		if ( currentSection != nextSection ) {
			[currentSections replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:nextSection]];
			// have we crossed the line?
			if ( currentSection == lastSection ) {
				if ( nextSection == 0 )
					[trackCounts replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:([[trackCounts objectAtIndex:i] intValue] + 1)]];
			}
			else if ( currentSection == 0 ) {
				if ( nextSection == lastSection )
					[trackCounts replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:([[trackCounts objectAtIndex:i] intValue] - 1)]];
			}
		}
	}
	}
}
-(BOOL) checkCollisions
{
	BOOL collision = NO;
	int numsections = [track->sections count];
	int vehiclesCount = [vehicles count];
	for (int i = 0; i < vehiclesCount; i++) {
		Vehicle *vehiclei = (Vehicle*)[vehicles objectAtIndex:i];
		State *statei = [vehiclei nextState];
		int sectioni = [[nextSections objectAtIndex:i] intValue];
		for ( int j = i+1; j < vehiclesCount; j++ )
		{
			Vehicle *vehiclej = (Vehicle*)[vehicles objectAtIndex:j];
			State *statej = [vehiclej nextState];
			int sectionj = [[nextSections objectAtIndex:j] intValue];
			if (sectioni != sectionj
				&& ((sectioni +1) % numsections) != sectionj
				&& ((sectionj +1) % numsections) != sectioni
				) {
				continue;
			}
			float distMin = 0.5f*([vehiclei getWidth] + [vehiclej getWidth]);
			float dx = statei->x - statej->x;
			float dy = statei->y - statej->y;
			float distSq = dx*dx + dy*dy;
			if ( distSq > distMin*distMin || (dx == 0 && dy == 0) )
				continue;
			
			float dist = sqrtf( distSq );
			if ( dist == 0.0f )
				continue;
			dx /= dist;
			dy /= dist;
			
			[statei collide:0.5f*(statei->x +statej->x) 
						  Y:0.5f*(statei->y +statej->y) 
						 NX:dx 
						 NY:dy 
					   Body:vehiclej 
					  State:statej];
			collision = YES;
		}
	}
	return collision;
}
-(void)dealloc
{
	[track release];
	[vehicles release];
	[localVehicle release];
	[currentSections release];
	[nextSections release];
	[ranks release];
	[trackCounts release];
	[super dealloc];
}
@end
